use std::sync::Arc;

use axum::{
    Router,
    http::HeaderMap,
    response::{Html, IntoResponse},
    routing::get,
};

use askama::Template;
use reqwest::{StatusCode, header};
use tokio::sync::Mutex;

// 派生 Template 宏会自动查找 templates 目录下的同名文件
#[derive(Template)]
#[template(path = "index.html")] // 指定模板文件路径
struct IndexTemplate {
    title: String,
}

pub mod mov;
use mov::search_mov;
pub mod video;
use video::{video_h, video_post};

async fn index_handler() -> Html<String> {
    let template = IndexTemplate {
        title: "我的网站".to_string(),
    };
    Html(template.render().unwrap())
}

// 全局状态
#[derive(Clone)]
pub struct AppState {
    pub video_data: Arc<Mutex<mov::Mov>>,
}

use rust_embed::RustEmbed;

#[derive(RustEmbed)]
#[folder = "static/"] // 指定相对于 Cargo.toml 所在目录的路径
struct EmbeddedAssets;

#[tokio::main]
async fn main() {
    let state = Arc::new(AppState {
        video_data: Arc::new(Mutex::new(mov::Mov::new())),
    });

    // 静态文件服务：处理所有以 /static 开头的请求
    // let static_service = ServeDir::new("static");
    // .nest_service("/static", static_service)

    let app = Router::new()
        .route("/", get(index_handler).post(search_mov))
        .route("/video", get(video_h).post(video_post))
        .route("/static/{path}", get(serve_embedded_asset))
        .with_state(state);
    let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap();
    println!("服务器监听于 http://192.168.31.10:3000");
    axum::serve(listener, app).await.unwrap();
}

async fn serve_embedded_asset(path: axum::extract::Path<String>) -> impl IntoResponse {
    // 获取请求的文件路径
    let filename = path.0;
    // 尝试从嵌入的资源中获取文件
    match EmbeddedAssets::get(&filename) {
        Some(content) => {
            // 根据文件扩展名推断 MIME 类型（内容类型）
            let mime_type = mime_guess::from_path(&filename).first_or_octet_stream();
            let mut headers = HeaderMap::new();
            headers.insert(header::CONTENT_TYPE, mime_type.as_ref().parse().unwrap());
            // 可以设置缓存控制头等，例如：
            // headers.insert(header::CACHE_CONTROL, "public, max-age=86400".parse().unwrap());

            (StatusCode::OK, headers, content.data).into_response()
        }
        None => {
            // 文件未找到，返回 404
            (StatusCode::NOT_FOUND, "File not found").into_response()
        }
    }
}
